package com.ruoyi.biz.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.ruoyi.biz.domain.BizProject;
import com.ruoyi.biz.domain.BizProjectPlan;
import com.ruoyi.biz.enums.ProjectStatusEnum;
import com.ruoyi.biz.mapper.BizProjectMapper;
import com.ruoyi.biz.model.req.InvoiceProjectReq;
import com.ruoyi.biz.model.resp.BizInvoiceResp;
import com.ruoyi.biz.model.resp.InvoiceProjectResp;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.biz.mapper.BizInvoiceMapper;
import com.ruoyi.biz.domain.BizInvoice;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import static com.ruoyi.common.utils.SecurityUtils.getUserId;


/**
 * 项目开票Service业务层处理
 *
 * @author tianl
 * @date 2024-12-31
 */
@Service
public class BizInvoiceService extends ServiceImpl<BizInvoiceMapper, BizInvoice> {
    @Autowired
    private ProjectQueryService projectQueryService;
    @Autowired
    private BizProjectPlanService bizProjectPlanService;
    @Autowired
    private BizProjectMapper bizProjectMapper;

    public BigDecimal surplus(Long projectId) {
        BizProject bizProject = bizProjectMapper.selectById(projectId);
        if (bizProject != null) {
            List<BizInvoiceResp> list = baseMapper.listByProjectIds(Arrays.asList(projectId));
            BigDecimal total = list.stream().map(BizInvoiceResp::getInvoiceMoney).reduce(BigDecimal.ZERO, BigDecimal::add); // 计算总和
            BigDecimal surplus = bizProject.getTotalAmount().subtract(total);
            if (surplus.compareTo(BigDecimal.ZERO) <= 0) {
                return BigDecimal.ZERO;
            }
            return surplus;
        }
        return BigDecimal.ZERO;
    }

    /**
     * 分页查询项目开票
     */
    public IPage<InvoiceProjectResp> listPage(InvoiceProjectReq req) {
        IPage<InvoiceProjectResp> projectPage = projectQueryService.listInvoice(req);
        List<Long> projectIds = projectPage.getRecords().stream().map(InvoiceProjectResp::getProjectId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(projectIds)) {
            return projectPage;
        }
        List<BizProjectPlan> plans = bizProjectPlanService.listByProjectIds(projectIds, 1);
        List<BizInvoiceResp> invoices = baseMapper.listByProjectIds(projectIds);
        if (req.getInvoiceTimeStart() != null && req.getInvoiceTimeEnd() != null) {
            invoices = invoices.stream()
                    .filter(r -> r.getInvoiceTime().compareTo(req.getInvoiceTimeStart()) >= 0
                            && r.getInvoiceTime().compareTo(req.getInvoiceTimeEnd()) <= 0)
                    .collect(Collectors.toList());
        }
        Map<Long, List<BizProjectPlan>> projectPlanMap = plans.stream().collect(Collectors.groupingBy(BizProjectPlan::getProjectId));
        Map<Long, List<BizInvoiceResp>> projectMap = invoices.stream().collect(Collectors.groupingBy(BizInvoiceResp::getProjectId));
        for (InvoiceProjectResp resp : projectPage.getRecords()) {
            int planNum = 1;
            if (projectPlanMap.containsKey(resp.getProjectId())) {
                resp.setPlanList(projectPlanMap.get(resp.getProjectId()));
                planNum = projectPlanMap.get(resp.getProjectId()).size();
            } else {
                BizProjectPlan tmp = new BizProjectPlan();
                tmp.setStage("默认开票");
                tmp.setTime("-");
                resp.setPlanList(Arrays.asList(tmp));
            }
            resp.setInvoicePlan(planNum);
            if (projectMap.containsKey(resp.getProjectId())) {
                List<BizInvoiceResp> invoiceList = projectMap.get(resp.getProjectId());
                BigDecimal total = invoiceList.stream().map(BizInvoiceResp::getInvoiceMoney).reduce(BigDecimal.ZERO, BigDecimal::add); // 计算总和
                resp.setInvoiceList(invoiceList);
                resp.setInvoiceAmount(total);
                BigDecimal sub = resp.getTotalAmount().subtract(total);
//                if (sub.compareTo(BigDecimal.ZERO) <= 0) {
//                    sub = BigDecimal.ZERO;
//                }
                resp.setUnInvoiceAmount(sub);
                resp.setInvoiceReal(invoiceList.size());
            } else {
                resp.setInvoiceList(new ArrayList<>());
                resp.setInvoiceAmount(BigDecimal.ZERO);
                resp.setUnInvoiceAmount(resp.getTotalAmount());
                resp.setInvoiceReal(0);
            }
        }
        return projectPage;
    }

    /**
     * 查询项目开票列表
     */
    public List<BizInvoiceResp> list(InvoiceProjectReq req) {
        List<InvoiceProjectResp> projectPage = projectQueryService.listAllInvoice(req);
        List<Long> projectIds = projectPage.stream().map(InvoiceProjectResp::getProjectId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(projectIds)) {
            return new ArrayList<>();
        }
        List<BizInvoiceResp> invoices = baseMapper.listByProjectIds(projectIds);
        if (req.getInvoiceTimeStart() != null && req.getInvoiceTimeEnd() != null) {
            invoices = invoices.stream()
                    .filter(r -> r.getInvoiceTime().compareTo(req.getInvoiceTimeStart()) >= 0
                            && r.getInvoiceTime().compareTo(req.getInvoiceTimeEnd()) <= 0)
                    .collect(Collectors.toList());
        }
        return invoices;
    }


    public List<BizInvoiceResp> listExport(InvoiceProjectReq req) {
        List<Long> invalidProjectIds = baseMapper.listInvalid();
        List<InvoiceProjectResp> projectPage = projectQueryService.listAllInvoice(req);
        List<Long> projectIds = projectPage.stream().map(InvoiceProjectResp::getProjectId).collect(Collectors.toList());
        projectIds.removeAll(invalidProjectIds);
        if (CollectionUtils.isEmpty(projectIds)) {
            return new ArrayList<>();
        }
        List<BizInvoiceResp> invoices = baseMapper.listByProjectIds(projectIds);
        if (req.getInvoiceTimeStart() != null && req.getInvoiceTimeEnd() != null) {
            invoices = invoices.stream()
                    .filter(r -> r.getInvoiceTime().compareTo(req.getInvoiceTimeStart()) >= 0
                            && r.getInvoiceTime().compareTo(req.getInvoiceTimeEnd()) <= 0)
                    .collect(Collectors.toList());
        }
        return invoices;
    }

    /**
     * 根据ID查询
     */
    public BizInvoiceResp selectById(Long id) {
        return baseMapper.selectDetail(id);
    }

    /**
     * 新增修改项目开票
     */
    @Transactional(rollbackFor = Exception.class)
    public void beforeSave(BizInvoice bizInvoice) {
        BizProject bizProject = bizProjectMapper.selectById(bizInvoice.getProjectId());
        if (bizProject == null) {
            throw new ServiceException("项目信息异常");
        }
        if (bizInvoice.getId() != null) {
            bizInvoice.setUpdateTime(DateUtils.getNowDate());
        } else {
            bizInvoice.setCreateTime(DateUtils.getNowDate());
            bizInvoice.setUpdateTime(DateUtils.getNowDate());
            bizInvoice.setUserId(getUserId());
            bizInvoice.setInvoiceUserId(getUserId());
        }
        saveOrUpdate(bizInvoice);
        if (bizProject.getProjectStatus().compareTo(ProjectStatusEnum.RECEIPT.getCode()) < 0) {
            bizProject.setProjectStatus(ProjectStatusEnum.RECEIPT.getCode());
            bizProjectMapper.updateById(bizProject);
        }
    }

    /**
     * 批量删除项目开票
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteByIds(Long[] ids) {
        return baseMapper.deleteBatchIds(Arrays.asList(ids));
    }

}
